def equal_subranges(xs, eq, max_size=None):
    """
    Given a list and an equality operator, return maximal sub-ranges that
    satisfy `eq(·,·)` within each sub-range. If ``max_size`` is specified,
    the constraint of maximal size also applies.

    Args:
        xs:
            a list of elements
        eq:
            equality operator

        max_size:
            the maximal size of subrange.

    Returns:
        maximal equal sub-ranges of at most ``max_size`` elements.
    """

    result = []
    not_equal = False
    for x in xs:
        if len(result) == 0:
            result.append(x)
        elif eq(result[0], x):
            result.append(x)
        else:
            not_equal = True

        if not_equal:
            yield result
            result = [x]
            not_equal = False
        elif max_size is not None and len(result) == max_size:
            yield result
            result = []

    if len(result) != 0:
        yield result


def fixed_width_subranges(xs, width):
    """
    Given a list ``xs`` and a integer ``width``, return a generator
    over consecutive subranges all of which are of fixed length
    specified by ``width`` except the last.

    Args:
        xs:
            a list of elements.
        width:
            the maximal length of a subrange.
    Returns:
        a generator of subranges.
    """
    assert width > 0

    count = 0
    result = []

    for x in xs:
        count += 1
        result.append(x)
        if count == width:
            yield result
            result, count = [], 0

    if len(result) != 0:
        yield result
